"""任务调度模块"""
import time
import threading
from datetime import datetime
from typing import Callable, Optional
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent))
from utils.logger import get_logger

logger = get_logger()


class TaskScheduler:
    """任务调度器"""
    
    def __init__(self, start_time: str, task_func: Callable, *args, **kwargs):
        """
        初始化任务调度器
        
        Args:
            start_time: 开始时间，格式为 'YYYY-MM-DD HH:MM:SS' 或 '0'（立即执行）
            task_func: 要执行的任务函数
            *args: 任务函数的位置参数
            **kwargs: 任务函数的关键字参数
        """
        self.start_time = start_time
        self.task_func = task_func
        self.args = args
        self.kwargs = kwargs
        self.is_running = False
        self.thread: Optional[threading.Thread] = None
    
    def _parse_time(self) -> Optional[datetime]:
        """
        解析时间字符串
        
        Returns:
            datetime对象，如果为立即执行返回None
        """
        # 处理立即执行的情况
        if str(self.start_time).strip() == '0':
            logger.info("检测到立即执行模式（start_time = 0）")
            return None
        
        try:
            # 支持多种时间格式
            time_formats = [
                '%Y-%m-%d %H:%M:%S',
                '%Y/%m/%d %H:%M:%S',
                '%Y-%m-%d %H:%M',
                '%Y/%m/%d %H:%M',
            ]
            
            for fmt in time_formats:
                try:
                    target_time = datetime.strptime(str(self.start_time).strip(), fmt)
                    logger.info(f"成功解析时间：{target_time.strftime('%Y-%m-%d %H:%M:%S')}")
                    return target_time
                except ValueError:
                    continue
            
            logger.error(f"无法解析时间格式：{self.start_time}")
            raise ValueError(f"无法解析时间格式：{self.start_time}，支持的格式如：'2025-11-10 14:00:00'")
            
        except Exception as e:
            logger.error(f"解析时间时发生错误：{e}")
            raise
    
    def _wait_until_time(self, target_time: datetime):
        """
        等待直到指定时间
        
        Args:
            target_time: 目标时间
        """
        now = datetime.now()
        
        if target_time < now:
            logger.warning(f"目标时间 {target_time} 早于当前时间 {now}，将立即执行")
            return
        
        wait_seconds = (target_time - now).total_seconds()
        logger.info(f"当前时间：{now.strftime('%Y-%m-%d %H:%M:%S')}")
        logger.info(f"目标时间：{target_time.strftime('%Y-%m-%d %H:%M:%S')}")
        logger.info(f"等待时间：{wait_seconds:.2f} 秒（约 {wait_seconds/60:.2f} 分钟）")
        
        # 如果等待时间超过10秒，每隔一段时间显示倒计时
        if wait_seconds > 10:
            logger.info("开始等待，将定期显示倒计时...")
            
            # 每隔一定时间显示剩余时间
            display_interval = 30 if wait_seconds > 300 else 10  # 超过5分钟每30秒显示，否则每10秒
            
            while True:
                now = datetime.now()
                remaining = (target_time - now).total_seconds()
                
                if remaining <= 0:
                    break
                
                if remaining <= 10:
                    # 最后10秒每秒显示
                    logger.info(f"倒计时：{remaining:.1f} 秒")
                    time.sleep(1)
                elif remaining <= display_interval:
                    logger.info(f"剩余时间：{remaining:.1f} 秒")
                    time.sleep(1)
                else:
                    logger.info(f"剩余时间：{remaining/60:.2f} 分钟（{int(remaining)} 秒）")
                    time.sleep(display_interval)
        else:
            # 短时间等待，直接sleep
            time.sleep(wait_seconds)
        
        logger.info("⏰ 到达执行时间！")
    
    def _run_task(self):
        """内部任务运行方法"""
        try:
            logger.info("=" * 60)
            logger.info("任务调度器启动")
            logger.info("=" * 60)
            
            # 解析时间
            target_time = self._parse_time()
            
            # 如果不是立即执行，等待到指定时间
            if target_time is not None:
                self._wait_until_time(target_time)
            else:
                logger.info("立即执行模式，马上开始执行任务")
            
            # 执行任务
            logger.info("▶ 开始执行任务...")
            result = self.task_func(*self.args, **self.kwargs)
            
            if result:
                logger.info("✓ 任务执行成功！")
            else:
                logger.error("✗ 任务执行失败！")
            
            logger.info("=" * 60)
            logger.info("任务调度器结束")
            logger.info("=" * 60)
            
        except Exception as e:
            logger.error(f"任务执行过程中发生错误：{e}", exc_info=True)
        finally:
            self.is_running = False
    
    def start(self, blocking: bool = True):
        """
        启动调度器
        
        Args:
            blocking: 是否阻塞当前线程。True表示在当前线程执行，False表示在新线程执行
        """
        if self.is_running:
            logger.warning("调度器已在运行中")
            return
        
        self.is_running = True
        
        if blocking:
            # 在当前线程执行
            self._run_task()
        else:
            # 在新线程执行
            self.thread = threading.Thread(target=self._run_task, daemon=True)
            self.thread.start()
            logger.info("调度器已在后台线程启动")
    
    def stop(self):
        """停止调度器"""
        if not self.is_running:
            logger.warning("调度器未在运行")
            return
        
        self.is_running = False
        logger.info("正在停止调度器...")
        
        if self.thread and self.thread.is_alive():
            self.thread.join(timeout=5)
            logger.info("调度器已停止")
    
    def wait(self):
        """等待调度器完成"""
        if self.thread and self.thread.is_alive():
            self.thread.join()


def schedule_task(start_time: str, task_func: Callable, *args, 
                 blocking: bool = True, **kwargs) -> TaskScheduler:
    """
    快捷函数：调度任务
    
    Args:
        start_time: 开始时间
        task_func: 任务函数
        blocking: 是否阻塞
        *args: 任务函数参数
        **kwargs: 任务函数关键字参数
    
    Returns:
        TaskScheduler实例
    """
    scheduler = TaskScheduler(start_time, task_func, *args, **kwargs)
    scheduler.start(blocking=blocking)
    return scheduler

